﻿using AutoMapper;
using B.S.BaseData.Domain.Entities.Meeting;
using B.S.BaseData.Domain.Entities.RBAC;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.ErrorCode.ErrorCodes;
using B.S.BaseData.Infrastructure.Interfaces;
using B.S.DataBase.EFCoreServiers.Dtos.MeetingReservations;
using B.S.DataBase.EFCoreServiers.IServices.Meetings;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace B.S.DataBase.EFCoreServiers.Services.Meetings
{
    public class MeetingReservationServices : IMeetingReservationServices
    {
        private readonly IMeetingReservationRepository meetingReservation;
        private readonly IMeetingRoomRepository meetingRoom;
        private readonly IMeetingApprovalRepository meetingApproval;
        private readonly IMapper mapper;

        public MeetingReservationServices(
            IMeetingReservationRepository meetingReservation,
            IMapper mapper,
            IMeetingRoomRepository meetingRoom,
            IMeetingApprovalRepository meetingApproval)
        {
            this.meetingReservation = meetingReservation;
            this.mapper = mapper;
            this.meetingRoom = meetingRoom;
            this.meetingApproval = meetingApproval;
        }

        /// <summary>
        /// 添加会议室预约
        /// </summary>
        /// <param name="addReservationDto">预约信息</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> AddReservationAsync(AddMeetingReservationDto addReservationDto)
        {
            try
            {
                using (var tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 检查时间段是否已被预约
                        var exists = await meetingReservation.GetAll()
                            .AnyAsync(x => x.Subject==x.Subject
                                && x.StartTime < addReservationDto.EndTime
                                && x.EndTime > addReservationDto.StartTime);

                        if (exists)
                        {
                            return ApiResult.Fail("该时间段已被预约,或主题名称使用未结束", StatusCodeEnum.Fail);
                        }

                        var reservation = mapper.Map<MeetingReservation>(addReservationDto);


                        await meetingReservation.AddAsync(reservation);

                        //查询到刚才添加的数据 倒序 查第一条，也就是最后添加的数据
                        var reservationIndo = await meetingReservation.GetAll().Where(x => x.Subject == reservation.Subject).OrderByDescending(x=>x.MeetingReservationId).FirstOrDefaultAsync();
                        if (reservationIndo != null)
                        {
                            //添加审批记录
                            MeetingApproval approval = new MeetingApproval()
                            {
                                MeetingReservationId = reservationIndo.MeetingReservationId,
                                Result = null,
                                ApprovalThing = null,
                                State = 0,
                                UserId = addReservationDto.HostId,
                            };
                            await meetingApproval.AddAsync(approval);
                        }
                        else
                        {
                            throw new Exception("添加预约会议失败");
                        }

                        tran.Complete();

                        return ApiResult.Success(StatusCodeEnum.Ok);
                    }
                    catch (Exception)
                    {
                        tran.Dispose();
                        throw;
                    }
                }


             
            }
            catch (Exception ex)
            {
                return ApiResult.Fail("添加预约失败：" + ex.Message, StatusCodeEnum.Exception);
            }
        }

        /// <summary>
        /// 获取会议室预约列表
        /// </summary>
        /// <param name="queryDto">查询条件</param>
        /// <returns>预约列表</returns>
        public async Task<ApiResult<ApiPaging<GetMeetingReservationResponseDto>>> GetReservationListAsync(GetMeetingReservationDto queryDto)
        {
            try
            {
                // 获取预约列表
                var list = await meetingReservation.GetPageListAsync(
                    queryDto.pageIndex,
                    queryDto.pageSize,
                    x => true  // 不需要在这里过滤会议室名称
                );

                // 获取所有相关的会议室信息
                var roomIds = list.Data.Select(x => x.MeetingRoomId).Distinct().ToList();
                var rooms = await meetingRoom.GetAll()
                    .Where(r => roomIds.Contains(r.Id))
                    .ToDictionaryAsync(r => r.Id, r => r.Name);

                // 转换为DTO，并填充会议室名称
                var dto = list.Data.Select(x => new GetMeetingReservationResponseDto
                {
                    Id = x.MeetingReservationId,
                    Subject = x.Subject,
                    MeetingRoomName = rooms.GetValueOrDefault(x.MeetingRoomId, x.MeetingRoomName), // 从字典中获取会议室名称
                    HostId = x.HostId,
                    HostName = x.HostName,
                    MeetingDate = x.MeetingDate,
                    StartTime = x.StartTime,
                    EndTime = x.EndTime,
                    Status = x.Status,
                    IsRemoteMeeting = x.IsRemoteMeeting,
                    RequireSignIn = x.RequireSignIn,
                    AccessControlEnabled = x.AccessControlEnabled,
                    MeetingRoomId = x.MeetingRoomId,
                    Content = x.Content,
                    Participants = x.Participants,
                    SendSmsNotification = x.SendSmsNotification


                }).ToList();


                var pageDto = new ApiPaging<GetMeetingReservationResponseDto>(list.TotalCount, list.TotalPage, dto);
                return ApiResult<ApiPaging<GetMeetingReservationResponseDto>>.Success(pageDto, StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult<ApiPaging<GetMeetingReservationResponseDto>>.Fail(
                    "获取预约列表失败：" + ex.Message,
                    StatusCodeEnum.Exception
                );
            }
        }

        /// <summary>
        /// 更新会议室预约
        /// </summary>
        /// <param name="updateDto">更新的预约信息</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> UpdateReservationAsync(UpdateMeetingReservationDto updateDto)
        {
            try
            {
                // 检查预约是否存在
                var reservation = await meetingReservation.GetAll()
                    .FirstOrDefaultAsync(x => x.MeetingReservationId == updateDto.MeetingReservationId);
                if (reservation == null)
                {
                    return ApiResult.Fail("预约记录不存在", StatusCodeEnum.ObjNotFound);
                }

                // 检查时间段是否已被其他预约占用
                var exists = await meetingReservation.GetAll()
                    .AnyAsync(x => x.MeetingReservationId != updateDto.MeetingReservationId
                        && x.MeetingReservationId == updateDto.MeetingReservationId
                        && x.StartTime < updateDto.EndTime
                        && x.EndTime > updateDto.StartTime);

                if (exists)
                {
                    return ApiResult.Fail("该时间段已被预约", StatusCodeEnum.Fail);
                }

                mapper.Map(updateDto, reservation);
                await meetingReservation.UpdateAsync(reservation);

                return ApiResult.Success(StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult.Fail("更新预约失败：" + ex.Message, StatusCodeEnum.Exception);
            }
        }

        /// <summary>
        /// 删除会议室预约
        /// </summary>
        /// <param name="id">预约ID</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> DeleteReservationAsync(int id)
        {
            try
            {
                var reservation = await meetingReservation.GetAll()
                    .FirstOrDefaultAsync(x => x.MeetingReservationId == id);
                if (reservation == null)
                {
                    return ApiResult.Fail("预约记录不存在", StatusCodeEnum.ObjNotFound);
                }

                await meetingReservation.DeleteAsync(reservation);
                return ApiResult.Success(StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult.Fail("删除预约失败：" + ex.Message, StatusCodeEnum.Exception);
            }
        }

    }
}
